import { Command, Option } from 'clipanion'
import fg from 'fast-glob'
import inquirer, { Question } from 'inquirer'

import { spawn } from './spawn'

const packages = fg
  .sync(`${process.cwd()}/packages/**`, {
    cwd: 'dir',
    deep: 1,
    onlyDirectories: true,
  })
  .map((path) => path.split('/').pop()) as string[]

const question: Question = {
  type: 'list',
  name: 'Choose a package to build',
  choices: packages,
  prefix: '🛠',
}

type Package = typeof packages[number]
const getPackageName = (folderName: string) => {
  return require(`${process.cwd()}/packages/${folderName}/package.json`).name
}

export class BundleCommand extends Command {
  static paths = [[`bundle`]]

  project: Package = Option.String(`-p,--package`)!

  packages: Package = Option.String(`-ps,--packages`)!

  local = Option.Boolean(`-l,--local`, false)

  all = Option.Boolean(`-a,--all`, false)

  build = 'build'

  async execute() {
    if (this.project && !~packages.indexOf(this.project)) {
      throw new TypeError(`Plz input right package name.`)
    }
    if (this.packages) {
      const projectArr = this.packages.split(',')
      if (projectArr.length > 0) {
        return this.runMany(projectArr)
      }
    }
    this.local && (this.build = 'build-local')
    await this.prompt()
  }

  async runMany(projects: string[]) {
    const projectsString = projects.map(getPackageName).join(',')
    await spawn(`yarn nx run-many --nx-bail --target=${this.build} --projects=${projectsString}`)
  }

  async prompt() {
    if (this.all) {
      await spawn(`yarn nx run-many --nx-bail --target=${this.build}`)
      return
    }

    if (this.project) {
      return this.run(this.project)
    }

    const answer = await inquirer.prompt([question])
    await this.run(answer[question.name!])
  }

  async run(pkg: Package) {
    await spawn(`yarn nx run ${getPackageName(pkg)}:${this.build}`)
  }
}
